package cn.com.cfae.iras.doc.analyze.components.integrity;

import cn.com.cfae.iras.doc.analyze.components.BaseComponent;
import cn.com.cfae.iras.doc.analyze.components.beans.ComponentResult;
import cn.com.cfae.iras.doc.analyze.parse.kv.KVText;
import cn.com.cfae.iras.doc.analyze.parse.model.ExtractBizModel;
import cn.com.cfae.iras.doc.analyze.parse.model.ExtractItem;
import cn.com.cfae.iras.doc.analyze.parse.model.PageModel;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * Created by 佟媛媛 on 18/10/23.
 */

@Component("I1013")
@Scope("prototype")
public class I1013 extends BaseComponent {

    private static Logger log = LoggerFactory.getLogger(I1013.class);


    /**
     * @auth 佟媛媛
     * @date 18/10/29 下午7:13
     * @desc
     *对近一年或及一期占总资产10%以上的资产类科目、占总负债10%以上的负债类科目，或者变化幅度在30%以上的会计科目进行筛查，比对M-6-2具体科目分析中是否有遗漏缺失
     * 若某个科目满足前述披露条件，但未披露，提示“XX科目占总资产10%以上，但未披露具体内容”或“XX科目近一年或一期变化幅度超过30%以上，但未披露具体分析”
     * "1、该规则较复杂，进行规则拆分；
    2、资产类科目：
    2.1、检查资产类科目占比>10%的科目，同时检查该科目在会计科目分析章节是否有对应文字描述；公式：资产类科目/总资产；
    2.2、检查资产类科目≥30%的科目，同时检查该科目在会计科目分析章节是否有对应文字描述；举例：（2018年季报应收账款-2017年年报应收账款）/2017年年报应收账款；
    3、负债类科目：
    3.1、检查负债类科目占比>10%的科目，同时检查该科目在会计科目分析章节是否有对应文字描述；公式：负债类科目/总负债；
    3.2、检查负债类科目变化幅度≥30%的科目，同时检查该科目在会计科目分析章节是否有对应文字描述；举例：（2018年季报应付账款-2017年年报应付账款）/2017年年报应付账款；
    4、提示缺失的会计分析科目；"

     资产类：
        (HBZJ, "货币资金");
        (YSPJJYSZK, "应收票据及应收账款");
        (YFKX, "预付款项");
        (QTYSK, "其他应收款");
        (CH, "存货");
        (CYDSFZ, "持有待售负债");
        (YNNDQFLDZC, "一年内到期的非流动资产");
        (QTLDZC, "其他流动资产");
        (KGCSJRZC, "可供出售金融资产");
        (CYZDQTZ, "持有至到期投资");
        (CQYSK, "长期应收款");
        (CQGQTZ, "长期股权投资");
        (QTQYGJ, "其他权益工具");
        (TZXFDC, "投资性房地产");
        (KFZC, "开发支出");
        (GDZC, "固定资产");
        (ZJGC, "在建工程");
        (WXZC, "无形资产");
        (CQDTFY, "长期待摊费用");
        (DYSDSZC, "递延所得税资产");
        (QTFLDZC, "其他非流动资产");
     负债类：
        (DQJK, "短期借款");
        (YFPJJYFZK, "应付票据及应付账款");
        (YSKX, "预收款项");
        (YFZGXC, "应付职工薪酬");
        (YJSF, "应交税费");
        (YNNDQFLDFZ, "一年内到期的非流动负债");
        (QTLDFZ, "其他流动负债");
        (CQJK, "长期借款");
        (YFZQ, "应付债券");
        (YXG, "优先股");
        (YXZ, "永续债");
        (YJFZ, "预计负债");
        (DYSDSFZ, "递延所得税负债");
        (QTFLDFZ, "其他非流动负债");
        (CQYFK, "长期应付款");
        (DYSY, "递延收益");

     */
    Map<String,String> kmList = null;
    private static String[] zc = new String[]{"HBZJ","YSPJJYSZK","YFKX","QTYSK","CH","CYDSFZ","YNNDQFLDZC","QTLDZC","KGCSJRZC","CYZDQTZ","CQYSK","CQGQTZ","QTQYGJ", "TZXFDC","KFZC","GDZC","ZJGC","WXZC","CQDTFY","DYSDSZC","QTFLDZC"};
    private static String[] fz = new String[]{"DQJK","YFPJJYFZK","YSKX","YFZGXC","YJSF","YNNDQFLDFZ","QTLDFZ","CQJK","YFZQ","YXG","YXZ","YJFZ","DYSDSFZ","QTFLDFZ","CQYFK","DYSY"};
    @Override
    public List<ComponentResult> handlerM() {
        return common("M-6");
    }

    private List<ComponentResult> common(String catalogId){
        kmList = new HashMap<>();
        setCatalogId(catalogId);
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        List<ComponentResult> list = new ArrayList<>();
        ExtractBizModel model = getModel(getCatalogId(),"ZCFZ");//资产负债表
        List<ComponentResult> list1 = getList(get10(model),"科目占","%，但未披露具体内容");
        List<ComponentResult> list2 = getList(get30(model),"科目近一年或一期变化幅度","%，但未披露具体分析");
        list.addAll(list1);
        list.addAll(list2);
        if(CollectionUtils.isEmpty(list)){
            ComponentResult result = getComponentResult(true,"02","资产类科目占比、负债类科目占比",pageNum,"未抽取到数据",getRuleTitle(),null);
            list.add(result);
        }
        return list;
    }

    private List<ComponentResult> getList(Map<String,String> kmMap,String msg1,String msg2){
        List<ComponentResult> list = new ArrayList<>();
        for(String bk : kmMap.keySet()){
            boolean exist = false;
            int pageNum = getChapterModel(getCatalogId()).getStartPage();
            List<ComponentResult.TextPosition> textPositionList = new ArrayList<>();
            String promptMsg = "已披露";
            String v = kmMap.get(bk);
            try{
                for(int j=0;j<getChapterModel(getCatalogId()).getPageModelList().size();j++){
                    PageModel pageModel = getChapterModel(getCatalogId()).getPageModelList().get(j);
                    if(exist) break;
                    pageNum = pageModel.getPageNumber();
                    Map page = new HashMap();
                    JsonArray jsonTextDataArray = pageModel.getJsonTextData()!=null?pageModel.getJsonTextData().getAsJsonArray():null;
                    if(jsonTextDataArray!=null) {
                        for (JsonElement element : jsonTextDataArray) {
                            if(exist) break;
                            JsonArray data = element.getAsJsonObject() != null ? element.getAsJsonObject().getAsJsonArray("data") : null;//当页文本
                            if (data != null) {
                                for(int i=0;i<data.size();i++){
                                    if(exist) break;
                                    JsonObject current = returnOne(data.get(i).getAsJsonArray());
                                    String content = current.get("text").getAsString();
                                    if(Pattern.matches("\\d{1,2}、"+bk.split("##")[1]+"[\\S\\s]*",content)){
                                        exist = true;
                                        page.put("pageNum",pageNum);page.put("lineNum",i);
                                        double x = current.get("left").getAsDouble();
                                        double y = current.get("top").getAsDouble();
                                        ComponentResult.TextPosition textPosition = new ComponentResult().new TextPosition();
                                        textPosition.setContent(content);
                                        textPosition.setX(x);
                                        textPosition.setY(y);
                                        textPositionList.add(textPosition);
                                    }
                                }
                            }
                        }
                    }
                    if(exist){
//                        if(jsonTextDataArray!=null) {
//                            for (JsonElement element : jsonTextDataArray) {
//                                JsonArray data = element.getAsJsonObject() != null ? element.getAsJsonObject().getAsJsonArray("data") : null;//当页文本
//                                Result result = getTextPositionList(data,page,pageModel,j);
//                                List<ComponentResult.TextPosition> _textPositionList = result.getList();
//                                textPositionList.addAll(_textPositionList);
//                                boolean boo = result.isBoo();
//                                if(!boo && _textPositionList.size()<5){
//                                    int lines = _textPositionList.size();
//                                    if(j<=getChapterModel(getCatalogId()).getPageModelList().size()-2){//连续判断下一页
//                                        PageModel _pageModel = getChapterModel(getCatalogId()).getPageModelList().get(j+1);
//                                        JsonArray _jsonTextDataArray = _pageModel.getJsonTextData()!=null?_pageModel.getJsonTextData().getAsJsonArray():null;
//                                        if(_jsonTextDataArray!=null){
//                                            List<ComponentResult.TextPosition> _list = new ArrayList<>();
//                                            for (JsonElement _element : _jsonTextDataArray) {
//                                                JsonArray _data = _element.getAsJsonObject() != null ? _element.getAsJsonObject().getAsJsonArray("data") : null;//当页文本
//                                                page.put("pageNum",pageNum+1);page.put("lineNum",0);
//                                                Result _result = getTextPositionList(_data,page,_pageModel,j);
//                                                List<ComponentResult.TextPosition> __textPositionList = _result.getList();
//                                                lines += __textPositionList.size();
//                                                _list.addAll(__textPositionList);
//                                            }
//                                            if(lines<5){
//                                                exist = false;
//                                            }else{
////                                                textPositionList.addAll(_list);
//                                            }
//                                        }
//                                    }
//                                }
//                            }
//                        }

                        promptMsg = msg1+("负债类".equals(bk.split("##")[0])?"总负债":"总资产")+getTwoDecimal(Double.valueOf(v)*100)+"%";
                    }else{
                        promptMsg = msg1+("负债类".equals(bk.split("##")[0])?"总负债":"总资产")+getTwoDecimal(Double.valueOf(v)*100)+msg2;
                    }

                }
            }catch (Exception e){
                log.error(e.getMessage(),e);
            }
            ComponentResult result = getComponentResult(!exist,exist?"01":"02",bk.replace("##","-"),pageNum,promptMsg,getRuleTitle(),textPositionList);
            list.add(result);
        }
        return list;
    }

    private Result getTextPositionList(JsonArray data,Map page,PageModel pageModel,int j){
        Result result = new Result();
        List<ComponentResult.TextPosition> textPositionList = new ArrayList<>();
        if (data != null) {
            List<ComponentResult.TextPosition> _textPositionList = new ArrayList<>();
            for(int i=(int)page.get("lineNum")+1;i<data.size();i++){
                JsonObject current = returnOne(data.get(i).getAsJsonArray());
                String content = current.get("text").getAsString();
                double x = current.get("left").getAsDouble();
                double y = current.get("top").getAsDouble();
                ComponentResult.TextPosition textPosition = new ComponentResult().new TextPosition();
                textPosition.setContent(content);
                textPosition.setX(x);
                textPosition.setY(y);
                _textPositionList.add(textPosition);
                if(Pattern.matches("\\d{1,2}、[\\S\\s]*",content)){//到下一章节
                    if(i-(int)page.get("lineNum")>=5){
                        _textPositionList.remove(_textPositionList.size()-1);
                        result.setBoo(true);
                        break;
                    }
                }else if(data.size()-(int)page.get("lineNum")>=5 && i==data.size()-1){//到当前页最后
                    result.setBoo(true);
                    break;
                }else{
                    result.setBoo(false);
                }
            }
            textPositionList.addAll(_textPositionList);
        }
        result.setList(textPositionList);
        return result;
    }

    public class Result{
        private List<ComponentResult.TextPosition> list;
        private boolean boo;

        public List<ComponentResult.TextPosition> getList() {
            return list;
        }

        public void setList(List<ComponentResult.TextPosition> list) {
            this.list = list;
        }

        public boolean isBoo() {
            return boo;
        }

        public void setBoo(boolean boo) {
            this.boo = boo;
        }
    }


    private Map get30(ExtractBizModel model){
        Map<String,String> kmMap = new HashMap();
        Map m1 = getfzhj30(model);
        Map m2 = getzczj30(model);
        kmMap.putAll(m1);
        kmMap.putAll(m2);
        return kmMap;
    }

    private Map getfzhj30(ExtractBizModel model){
        Map<String,String> kmMap = new HashMap();
        String jyq = getJYQ(model.getTables());//近一期
        String jyn = getJYN(model.getTables());//近一年
        Map<String, ExtractItem> coljyn = model.getTable(jyn);
        Map<String, ExtractItem> coljyq = model.getTable(jyq);
        Map<String,Double> mapjyn = new HashMap<>();
        Map<String,Double> mapjyq = new HashMap<>();
        for(String  item : fz){
            double d = getDouble(coljyn,item);
            String s = getName(coljyn,item);
            if(StringUtils.isNotEmpty(s)) mapjyn.put(s,d);
        }
        for(String  item : fz){
            double d = getDouble(coljyq,item);
            String s = getName(coljyq,item);
            if(StringUtils.isNotEmpty(s)) mapjyq.put(s,d);
        }
        if(MapUtils.isNotEmpty(mapjyn) && MapUtils.isNotEmpty(mapjyq)){
            for(Map.Entry<String,Double> entry : mapjyn.entrySet()){
                Double jynd = entry.getValue();
                Double jyqd = mapjyq.get(entry.getKey());
                if(jynd!=null && jyqd!=null && jynd!=0){
                    double v = (jyqd-jynd)/jynd;
                    if(Math.abs(v)>0.3) kmMap.put("负债类##"+entry.getKey(),v+"");
                }
            }
        }
        return kmMap;
    }

    private Map getzczj30(ExtractBizModel model){
        Map<String,String> kmMap = new HashMap();
        String jyq = getJYQ(model.getTables());//近一期
        String jyn = getJYN(model.getTables());//近一年
        Map<String, ExtractItem> coljyn = model.getTable(jyn);
        Map<String, ExtractItem> coljyq = model.getTable(jyq);
        Map<String,Double> mapjyn = new HashMap<>();
        Map<String,Double> mapjyq = new HashMap<>();
        for(String  item : zc){
            double d = getDouble(coljyn,item);
            String s = getName(coljyn,item);
            if(StringUtils.isNotEmpty(s)) mapjyn.put(s,d);
        }
        for(String  item : zc){
            double d = getDouble(coljyq,item);
            String s = getName(coljyq,item);
            if(StringUtils.isNotEmpty(s)) mapjyq.put(s,d);
        }
        for(Map.Entry<String,Double> entry : mapjyn.entrySet()){
            Double jynd = entry.getValue();
            Double jyqd = mapjyq.get(entry.getKey());
            if(jynd!=null && jyqd!=null && jynd!=0){
                double v = (jyqd-jynd)/jynd;
                if(Math.abs(v)>0.3) kmMap.put("资产类##"+entry.getKey(),v+"");
            }
        }
        return kmMap;
    }

    private Map get10(ExtractBizModel model){
        String jyq = getJYQ(model.getTables());//近一期
        String jyn = getJYN(model.getTables());//近一年
        Map<String,String> kmMap = new HashMap();
        Map m1 = getzczj10(model,jyq);
        Map m2 = getzczj10(model,jyn);
        Map m3 = getfzhj10(model,jyq);
        Map m4 = getfzhj10(model,jyn);
        kmMap.putAll(m1);
        kmMap.putAll(m2);
        kmMap.putAll(m3);
        kmMap.putAll(m4);
        return kmMap;
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/27 下午4:45
     * @desc 负债类
     */
    private Map getfzhj10(ExtractBizModel model,String jyn){
        Map<String,String> kmMap = new HashMap();
        Map<String, ExtractItem> col = model.getTable(jyn);
        double FZHJ = getDouble(col,"FZHJ");
        Map<Double,String> map = new HashMap<>();
        for(String  item : fz){
            double d = getDouble(col,item);
            String s = getName(col,item);
            if(StringUtils.isNotEmpty(s)) map.put(d,s);
        }

        for(Map.Entry<Double,String> entry : map.entrySet()){
            double d = entry.getKey();
            String s = entry.getValue();
            if(FZHJ!=0 && d/FZHJ>0.1){
                kmMap.put("负债类##"+s,d/FZHJ+"");
            }
        }
        return kmMap;
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/27 下午4:45
     * @desc 资产类
     */
    private Map getzczj10(ExtractBizModel model,String jyn){
        Map<String,String> kmMap = new HashMap();
        Map<String, ExtractItem> col = model.getTable(jyn);
        double ZCZJ = getDouble(col,"ZCZJ");
        Map<Double,String> map = new HashMap<>();
        for(String  item : zc){
            double d = getDouble(col,item);
            String s = getName(col,item);
            if(StringUtils.isNotEmpty(s)) map.put(d,s);
        }

        for(Map.Entry<Double,String> entry : map.entrySet()){
            double d = entry.getKey();
            String s = entry.getValue();
            if(ZCZJ!=0 && d/ZCZJ>0.1){
                kmMap.put("资产类##"+s,d/ZCZJ+"");
            }
        }
//        if(col!=null){
//            for(Map.Entry<String, ExtractItem> entry : col.entrySet()){
//                String key = entry.getKey();
//                ExtractItem _item = entry.getValue();
//                if(_item!=null && _item.getSynonyms().length>0){
//                    kmList.put(key,_item.getSynonyms()[0]);
//                    if(_item.getValue()!=null){
//                        if(zczj!=0){
//                            double v = getDouble(_item.getValue().getText());
//                            if(v/zczj>0.1 && v/zczj-1!=0){
//                                kmMap.put(_item.getSynonyms()[0],v/zczj+"");
//                            }
//                        }
//                    }
//                }
//            }
//        }
        return kmMap;
    }

    private double getDouble(Map<String, ExtractItem> col,String key){
        double zczj = 0;
        if(col!=null){
            ExtractItem item = col.get(key);
            if(item!=null && item.getValue()!=null){
                KVText ZCZJ_kvText = item.getValue();
                zczj = getDouble(ZCZJ_kvText.getText());
            }
        }
        return zczj;
    }

    private String getName(Map<String, ExtractItem> col,String key){
        String zczj = null;
        if(col!=null){
            ExtractItem item = col.get(key);
            if(item!=null && item.getKey()!=null){
                zczj = item.getKey().getText();
            }
        }
        return zczj;
    }

    @Override
    public List<ComponentResult> handlerBM() {
        return common("BM-6");
    }

    @Override
    public List<ComponentResult> handlerDM() {
        return common("DM-6");
    }

    @Override
    public List<ComponentResult> handlerBDM() {
        return common("BDM-6");
    }



    private ComponentResult getComponentResult(boolean annotationFlag,String exist,String keyword,int pageNum,String promptMsg,String ruleName,List<ComponentResult.TextPosition> textPositionList){
        ComponentResult result = new ComponentResult();
        result.setAnnotationFlag(annotationFlag);
        result.setCatalogId(getCatalogId());
        result.setChapterId(getChapterId());
        result.setExist(exist);
        result.setKeyword(keyword);
        result.setPageNum(pageNum);
        result.setPromptMessage(promptMsg);
        result.setRegulationId(getRegulationId());
        result.setRuleName(ruleName);
        result.setTextPosition(textPositionList);
        result.setUid(UUID.randomUUID().toString());
        return result;
    }

}
